/**
 * @file 0502_shared_weak_ptr.cpp
 * @author Kun (kun_g@msn.com)
 * @brief shared_ptr和weak_ptr的使用
 * @version 0.1
 * @date 2024-06-10
 *
 * @copyright Copyright (c) 2024
 *
 */
#include <iostream>
#include <memory>
#include <string>
#include <vector>

using namespace std;

class Person {
public:
  std::string name;
  shared_ptr<Person> mother;
  shared_ptr<Person> father;
  //! 采用如下方式，会造成循环引用，无法释放指针
  // vector<shared_ptr<Person>> kids;
  vector<weak_ptr<Person>> kids;

  Person(const std::string &n, shared_ptr<Person> m = nullptr,
         shared_ptr<Person> d = nullptr)
      : name(n), mother(m), father(d) {}

  ~Person() { cout << "Person " << name << " is being destroyed" << endl; }

  void add_kid(shared_ptr<Person> kid) { kids.push_back(kid); }
};

shared_ptr<Person> init_family(const std::string &name) {
  shared_ptr<Person> mother(new Person(name + "'s mother"));
  shared_ptr<Person> father(new Person(name + "'s father"));
  shared_ptr<Person> kid(new Person(name, mother, father));
  mother->add_kid(kid);
  father->add_kid(kid);
  return kid;
}

int main() {
  shared_ptr<Person> p = init_family("Alice");

  cout << "Alice's family exists" << endl;
  cout << "- Alice is shared " << p.use_count() << " times" << endl;
  //! 使用weak_ptr 需要使用lock()，
  // lock()方法返回的是一个shared_ptr，如果weak_ptr指向的对象已经被释放，lock()方法将返回一个空shared_ptr
  cout << "- name of 1st kid's mother: " << p->mother->kids[0].lock()->name
       << endl;
  // cout << "- name of 1st kid's mother: " << p->mom->kids[0]->name << endl;

  p = init_family("Bob");

  cout << "Bob's family exists" << endl;
}